﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using LANChatCore;

namespace LANChatClient
{
    public partial class ClientMain : Form
    {
        /// <summary>
        /// The main client class. Encapsulates everything that has to do with the client
        /// </summary>
        public ClientMain()
        {
#if DEBUG
            RevertSettings();
#endif
            InitializeComponent();
            LoadSettings();
            #region DEBUG
#if !DEBUG
            DEBUGDEBUGMenu.Visible = false;
#endif
            #endregion
        }

        private void LoadSettings()
        {
            #region load strings
            if (Properties.Settings.Default.Language == "")
            {
                Properties.Settings.Default.Language = "en";
            }
            LoadStrings(Properties.Settings.Default.Language);
            #endregion
            #region load theme
            if (Properties.Settings.Default.Theme == "")
            {
                Properties.Settings.Default.Theme = "default";
                Properties.Settings.Default.Save();
            }
            setScheme(Properties.Settings.Default.Theme);
            ClientUntickAllColour();
            if (Properties.Settings.Default.Theme == "default")
            {
                msColourSchemeDefault.Checked = true;
            }
            else
            {
                msColourSchemeClassic.Checked = true;
            }
            #endregion
            #region load settings
            msHideOnClose.Checked = Properties.Settings.Default.HideOnClose;
            msHideOnMinimise.Checked = Properties.Settings.Default.HideOnMinimise;
            msSound.Checked = Properties.Settings.Default.Sound;

            ClientUntickAllColour();
            if (Properties.Settings.Default.Theme == "default")
            {
                msColourSchemeDefault.Checked = true;
            }
            else
            {
                msColourSchemeClassic.Checked = true;
            }
            #endregion
        }

        private static void RevertSettings()
        {
            Properties.Settings.Default.Language = "en";
            Properties.Settings.Default.Theme = "default";
            Properties.Settings.Default.HideOnClose = false;
            Properties.Settings.Default.HideOnMinimise = false;
            Properties.Settings.Default.Sound = true;
            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Sets the programs colour scheme back to its defaults.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetDefaultColourScheme(object sender, EventArgs e)
        {
            if (msColourSchemeDefault.Checked == false)
            {
                //set colours
                setScheme("Default");

                //remove all ticks
                ClientUntickAllColour();

                //add tick the Default Colour Scheme Menu Item
                msColourSchemeDefault.Checked = true;
            }
        }

        /// <summary>
        /// Sets the programs colour scheme to a Green and Black DOS Style look.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetClassicColourScheme(object sender, EventArgs e)
        {
            if (msColourSchemeClassic.Checked == false)
            {
                //set colours
                setScheme("Classic");

                //remove all ticks
                ClientUntickAllColour();

                //add tick to Classic Colour Scheme Menu Item
                msColourSchemeClassic.Checked = true;
            }
        }

        /// <summary>
        /// Things to do upon the application closing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClientClosing(object sender, FormClosingEventArgs e)
        {
            //check if hide on close is enables
            if (Properties.Settings.Default.HideOnClose == true)
            {
                //if it is, hide the form etc
                //we dont actually want to close so cancel that
                e.Cancel = true;

                HideForm();
            }
            else
            {
                //otherwise, quit like normal
                QuitClient();

                /* Put in a seperate function to allow it
                 * to be called from other places */

            }
        }

        /// <summary>
        /// Set language to english
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetLanguageEnglish(object sender, EventArgs e)
        {
            LoadStrings("en");
            LogHelper.Log("Language set to English", System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// Set language to french
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetLanguageFrench(object sender, EventArgs e)
        {
            LoadStrings("fr");
            LogHelper.Log("Language set to French", System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// Set language to german
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetLanguageGerman(object sender, EventArgs e)
        {
            LoadStrings("de");
            LogHelper.Log("Language set to German", System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// Display the about box
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShowAbout(object sender, EventArgs e)
        {
            AboutForm about = new AboutForm();
            about.ShowDialog();
        }

        /// <summary>
        /// Removes all ticks from colour scheme menu items
        /// </summary>
        private void ClientUntickAllColour()
        {
            msColourSchemeClassic.Checked = false;
            msColourSchemeDefault.Checked = false;
        }

        /// <summary>
        /// Removes all ticks from language options
        /// </summary>
        private void ClientUntickAllLanguage()
        {
            msLanguageEnglish.Checked = false;
            msLanguageFrench.Checked = false;
            msLanguageGerman.Checked = false;
        }

        /// <summary>
        /// Sets a scheme from its name.
        /// Upon failure to find the theme file the application will run a catch and prompt the user about the failure.
        /// A Log entry is also made using the severity value of "Warning"
        /// </summary>
        /// <param name="ThemeName">The Name of the Scheme</param>
        private void setScheme(string ThemeName)
        {
            string filename = ThemeName.ToLower();
            byte[] resource;

            if (filename == "classic")
            {
                resource = Properties.Resources.classicscheme;
            }
            else
            {
                resource = Properties.Resources.defaultscheme;
            }

            MemoryStream ms = new MemoryStream(resource);            

            try
            {
                TextReader load = new StreamReader(ms);

                chatTextArea.ForeColor = Color.FromName(load.ReadLine());
                chatTextArea.BackColor = Color.FromName(load.ReadLine());

                listChatUsers.ForeColor = Color.FromName(load.ReadLine());
                listChatUsers.BackColor = Color.FromName(load.ReadLine());

                txtInputBox.ForeColor = Color.FromName(load.ReadLine());
                txtInputBox.BackColor = Color.FromName(load.ReadLine());

                btnSend.ForeColor = Color.FromName(load.ReadLine());
                btnSend.BackColor = Color.FromName(load.ReadLine());

                this.ForeColor = Color.FromName(load.ReadLine());
                this.BackColor = Color.FromName(load.ReadLine());

                menuStrip.ForeColor = Color.FromName(load.ReadLine());
                menuStrip.BackColor = Color.FromName(load.ReadLine());

                msAbout.ForeColor = Color.FromName(load.ReadLine());
                msAbout.BackColor = Color.FromName(load.ReadLine());

                msBanUser.ForeColor = Color.FromName(load.ReadLine());
                msBanUser.BackColor = Color.FromName(load.ReadLine());

                msColourScheme.ForeColor = Color.FromName(load.ReadLine());
                msColourScheme.BackColor = Color.FromName(load.ReadLine());

                msColourSchemeClassic.ForeColor = Color.FromName(load.ReadLine());
                msColourSchemeClassic.BackColor = Color.FromName(load.ReadLine());

                msColourSchemeDefault.ForeColor = Color.FromName(load.ReadLine());
                msColourSchemeDefault.BackColor = Color.FromName(load.ReadLine());

                msCreateRoom.ForeColor = Color.FromName(load.ReadLine());
                msCreateRoom.BackColor = Color.FromName(load.ReadLine());

                msDiconnect.ForeColor = Color.FromName(load.ReadLine());
                msDiconnect.BackColor = Color.FromName(load.ReadLine());

                msHelp.ForeColor = Color.FromName(load.ReadLine());
                msHelp.BackColor = Color.FromName(load.ReadLine());

                msHideOnClose.ForeColor = Color.FromName(load.ReadLine());
                msHideOnClose.BackColor = Color.FromName(load.ReadLine());

                msHideOnMinimise.ForeColor = Color.FromName(load.ReadLine());
                msHideOnMinimise.BackColor = Color.FromName(load.ReadLine());

                msKickUser.ForeColor = Color.FromName(load.ReadLine());
                msKickUser.BackColor = Color.FromName(load.ReadLine());

                msLeaveRoom.ForeColor = Color.FromName(load.ReadLine());
                msLeaveRoom.BackColor = Color.FromName(load.ReadLine());

                msModerateRoom.ForeColor = Color.FromName(load.ReadLine());
                msModerateRoom.BackColor = Color.FromName(load.ReadLine());

                msRoom.ForeColor = Color.FromName(load.ReadLine());
                msRoom.BackColor = Color.FromName(load.ReadLine());

                msSettings.ForeColor = Color.FromName(load.ReadLine());
                msSettings.BackColor = Color.FromName(load.ReadLine());

                msShowHelp.ForeColor = Color.FromName(load.ReadLine());
                msShowHelp.BackColor = Color.FromName(load.ReadLine());


                msSilenceuser.ForeColor = Color.FromName(load.ReadLine());
                msSilenceuser.BackColor = Color.FromName(load.ReadLine());

                msSound.ForeColor = Color.FromName(load.ReadLine());
                msSound.BackColor = Color.FromName(load.ReadLine());

                msUnSilenceUser.ForeColor = Color.FromName(load.ReadLine());
                msUnSilenceUser.BackColor = Color.FromName(load.ReadLine());

                msUnBanUser.ForeColor = Color.FromName(load.ReadLine());
                msUnBanUser.BackColor = Color.FromName(load.ReadLine());

                msLanguage.ForeColor = Color.FromName(load.ReadLine());
                msLanguage.BackColor = Color.FromName(load.ReadLine());

                msLanguageEnglish.ForeColor = Color.FromName(load.ReadLine());
                msLanguageEnglish.BackColor = Color.FromName(load.ReadLine());

                msLanguageFrench.ForeColor = Color.FromName(load.ReadLine());
                msLanguageFrench.BackColor = Color.FromName(load.ReadLine());

                msLanguageGerman.ForeColor = Color.FromName(load.ReadLine());
                msLanguageGerman.BackColor = Color.FromName(load.ReadLine());

                load.Close();

                //update Theme setting to themename
                Properties.Settings.Default.Theme = ThemeName;
                Properties.Settings.Default.Save();

                LogHelper.Log("Theme set to " + ThemeName, System.Diagnostics.TraceEventType.Information, "Settings");

            }
            catch(Exception e)
            {
                MessageBox.Show(string.Format(ErrorStrings.ThemeLoadFailed, ThemeName), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                LANChatCore.LogHelper.Log(string.Format(ErrorStrings.ThemeLoadFailed, ThemeName), System.Diagnostics.TraceEventType.Warning);
            }

        }

        /// <summary>
        /// Functions to run after the main form has been constructed, and initialised, but just before it is shown to the user.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Client_Load(object sender, EventArgs e)
        {
        }

        /// <summary>
        /// Loads strings from selected language
        /// </summary>
        /// <param name="languageCode">Language to use (en English, de German, fr French)</param>
        private void LoadStrings(string languageCode)
        {
            //remove all language ticks
            ClientUntickAllLanguage();


            if (languageCode == "en")
            {
                //load english strings
                msAbout.Text = ClientMainFormStringsEnglish.HelpMenuAbout;
                msBanUser.Text = ClientMainFormStringsEnglish.ModerateRoomMenuBanUser;
                msColourScheme.Text = ClientMainFormStringsEnglish.SettingsMenuColourScheme;
                msColourSchemeClassic.Text = ClientMainFormStringsEnglish.ColourSchemesMenuClassic;
                msColourSchemeDefault.Text = ClientMainFormStringsEnglish.ColourSchemesMenuDefault;
                msCreateRoom.Text = ClientMainFormStringsEnglish.RoomMenuCreateRoom;
                msDiconnect.Text = ClientMainFormStringsEnglish.MenuStripDisconnect;
                msHelp.Text = ClientMainFormStringsEnglish.MenuStripHelp;
                msHideOnClose.Text = ClientMainFormStringsEnglish.SettingsMenuHideOnClose;
                msHideOnMinimise.Text = ClientMainFormStringsEnglish.SettingsMenuHideOnMinimise;
                msKickUser.Text = ClientMainFormStringsEnglish.ModerateRoomMenuKickUser;
                msLeaveRoom.Text = ClientMainFormStringsEnglish.RoomMenuLeaveRoom;
                msModerateRoom.Text = ClientMainFormStringsEnglish.RoomMenuModerateRoom;
                msRoom.Text = ClientMainFormStringsEnglish.MenuStripRoom;
                msSettings.Text = ClientMainFormStringsEnglish.MenuStripSettings;
                msShowHelp.Text = ClientMainFormStringsEnglish.HelpMenuShowHelp;
                msSilenceuser.Text = ClientMainFormStringsEnglish.ModerateRoomMenuSilenceUser;
                msSound.Text = ClientMainFormStringsEnglish.SettingsMenuSound;
                msUnSilenceUser.Text = ClientMainFormStringsEnglish.ModerateRoomMenuUnSilenceuser;
                msLanguage.Text = ClientMainFormStringsEnglish.SettingsMenuLanguage;
                msUnBanUser.Text = ClientMainFormStringsEnglish.ModerateRoomMenuUnBanUser;

                btnSend.Text = ClientMainFormStringsEnglish.ButtonSend;

                //set tray icon strings
                trayContextMenu.Items[0].Text = ClientTrayMenuStringsEnglish.Show;
                trayContextMenu.Items[1].Text = ClientTrayMenuStringsEnglish.Quit;

                //add tick to language english option
                msLanguageEnglish.Checked = true;

                //set user variable language to "en"
                Properties.Settings.Default.Language = "en";
            }
            else if (languageCode == "de")
            {
                //load german strings
                msAbout.Text = ClientMainFormStringsGerman.HelpMenuAbout;
                msBanUser.Text = ClientMainFormStringsGerman.ModerateRoomMenuBanUser;
                msColourScheme.Text = ClientMainFormStringsGerman.SettingsMenuColourScheme;
                msColourSchemeClassic.Text = ClientMainFormStringsGerman.ColourSchemesMenuClassic;
                msColourSchemeDefault.Text = ClientMainFormStringsGerman.ColourSchemesMenuDefault;
                msCreateRoom.Text = ClientMainFormStringsGerman.RoomMenuCreateRoom;
                msDiconnect.Text = ClientMainFormStringsGerman.MenuStripDisconnect;
                msHelp.Text = ClientMainFormStringsGerman.MenuStripHelp;
                msHideOnClose.Text = ClientMainFormStringsGerman.SettingsMenuHideOnClose;
                msHideOnMinimise.Text = ClientMainFormStringsGerman.SettingsMenuHideOnMinimise;
                msKickUser.Text = ClientMainFormStringsGerman.ModerateRoomMenuKickUser;
                msLeaveRoom.Text = ClientMainFormStringsGerman.RoomMenuLeaveRoom;
                msModerateRoom.Text = ClientMainFormStringsGerman.RoomMenuModerateRoom;
                msRoom.Text = ClientMainFormStringsGerman.MenuStripRoom;
                msSettings.Text = ClientMainFormStringsGerman.MenuStripSettings;
                msShowHelp.Text = ClientMainFormStringsGerman.HelpMenuShowHelp;
                msSilenceuser.Text = ClientMainFormStringsGerman.ModerateRoomMenuSilenceUser;
                msSound.Text = ClientMainFormStringsGerman.SettingsMenuSound;
                msUnSilenceUser.Text = ClientMainFormStringsGerman.ModerateRoomMenuUnSilenceuser;
                msLanguage.Text = ClientMainFormStringsGerman.SettingsMenuLanguage;
                msUnBanUser.Text = ClientMainFormStringsGerman.ModerateRoomMenuUnBanUser;

                btnSend.Text = ClientMainFormStringsGerman.ButtonSend;

                //set tray icon strings
                trayContextMenu.Items[0].Text = ClientTrayMenuStringsGerman.Show;
                trayContextMenu.Items[1].Text = ClientTrayMenuStringsGerman.Quit;

                //add tick to language german option
                msLanguageGerman.Checked = true;

                //set user variable language to "de"
                Properties.Settings.Default.Language = "de";
            }
            else if (languageCode == "fr")
            {
                //load french strings
                msAbout.Text = ClientMainFormStringsFrench.HelpMenuAbout;
                msBanUser.Text = ClientMainFormStringsFrench.ModerateRoomMenuBanUser;
                msColourScheme.Text = ClientMainFormStringsFrench.SettingsMenuColourScheme;
                msColourSchemeClassic.Text = ClientMainFormStringsFrench.ColourSchemesMenuClassic;
                msColourSchemeDefault.Text = ClientMainFormStringsFrench.ColourSchemesMenuDefault;
                msCreateRoom.Text = ClientMainFormStringsFrench.RoomMenuCreateRoom;
                msDiconnect.Text = ClientMainFormStringsFrench.MenuStripDisconnect;
                msHelp.Text = ClientMainFormStringsFrench.MenuStripHelp;
                msHideOnClose.Text = ClientMainFormStringsFrench.SettingsMenuHideOnClose;
                msHideOnMinimise.Text = ClientMainFormStringsFrench.SettingsMenuHideOnMinimise;
                msKickUser.Text = ClientMainFormStringsFrench.ModerateRoomMenuKickUser;
                msLeaveRoom.Text = ClientMainFormStringsFrench.RoomMenuLeaveRoom;
                msModerateRoom.Text = ClientMainFormStringsFrench.RoomMenuModerateRoom;
                msRoom.Text = ClientMainFormStringsFrench.MenuStripRoom;
                msSettings.Text = ClientMainFormStringsFrench.MenuStripSettings;
                msShowHelp.Text = ClientMainFormStringsFrench.HelpMenuShowHelp;
                msSilenceuser.Text = ClientMainFormStringsFrench.ModerateRoomMenuSilenceUser;
                msSound.Text = ClientMainFormStringsFrench.SettingsMenuSound;
                msUnSilenceUser.Text = ClientMainFormStringsFrench.ModerateRoomMenuUnSilenceuser;
                msLanguage.Text = ClientMainFormStringsFrench.SettingsMenuLanguage;
                msUnBanUser.Text = ClientMainFormStringsFrench.ModerateRoomMenuUnBanUser;

                btnSend.Text = ClientMainFormStringsFrench.ButtonSend;

                //set tray icon strings
                trayContextMenu.Items[0].Text = ClientTrayMenuStringsFrench.Show;
                trayContextMenu.Items[1].Text = ClientTrayMenuStringsFrench.Quit;

                //add tick to language french option
                msLanguageFrench.Checked = true;

                //set user variable language to "fr"
                Properties.Settings.Default.Language = "fr";
            }
            else
            {
                LoadStrings("en");
                //if no language code is set, load english strings
            }
        }

        /// <summary>
        /// Turn off or on the hide on minimise feature
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toggleHideOnMinimise(object sender, EventArgs e)
        {
            msHideOnMinimise.Checked = !msHideOnMinimise.Checked;
            Properties.Settings.Default.HideOnMinimise = msHideOnMinimise.Checked;
            Properties.Settings.Default.Save();

            LogHelper.Log("Hide on Minimise set to " + msHideOnMinimise.Checked, System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// Turn on or off the hide on close feature
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toggleHideOnClose(object sender, EventArgs e)
        {
            msHideOnClose.Checked = !msHideOnClose.Checked;
            Properties.Settings.Default.HideOnClose = msHideOnClose.Checked;
            Properties.Settings.Default.Save();
            LogHelper.Log("Hide on Close set to " + msHideOnClose.Checked, System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// turn on or off sound alerts
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toggleSound(object sender, EventArgs e)
        {
            msSound.Checked = !msSound.Checked;
            Properties.Settings.Default.Sound = msSound.Checked;
            Properties.Settings.Default.Save();

            LogHelper.Log("Sound set to " + msSound.Checked, System.Diagnostics.TraceEventType.Information, "Settings");
        }

        /// <summary>
        /// Hides the main client form and displays the tray icon
        /// </summary>
        private void HideForm()
        {
            /*Put this in a seperate function as it is called from both functions for
             * hide on minimise and hide on close */
            //hide the form
            this.Hide();

            //make the tray icon visible
            trayIcon.Visible = true;
        }

        /// <summary>
        /// Closes the client, adds log entry and saves settings
        /// </summary>
        private void QuitClient()
        {
            string closeString;
            switch (Properties.Settings.Default.Language)
            {
                case "en":
                    closeString = ClientMainFormStringsEnglish.Quit;
                    break;
                case "fr": closeString = ClientMainFormStringsFrench.Quit;
                    break;
                case "de": closeString = ClientMainFormStringsGerman.Quit;
                    break;
                default:
                    closeString = ClientMainFormStringsEnglish.Quit;
                    break;
            }
            DialogResult result = MessageBox.Show(closeString,"", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                //Removes the tray icon as on some systems it remains after an application closes
                trayIcon.Visible = false;
                trayIcon.Icon = null;

                //saves changes to settings file
                Properties.Settings.Default.Save();

                //add a log for the client close
                LogHelper.Log(GeneralStrings.LanChatStop, System.Diagnostics.TraceEventType.Information);

                //kill the process
                System.Diagnostics.Process.GetCurrentProcess().Kill();
            }
        }

        /// <summary>
        /// UnHides the main client form, hides the tray icon
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void unHideFromTray(object sender, EventArgs e)
        {
            UnHide();
        }

        /// <summary>
        /// Unhides the client from the tray, hides the tray icon
        /// </summary>
        private void UnHide()
        {
            trayIcon.Visible = false;
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        /// <summary>
        /// Quits the client program from the tray
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void quitFromTray(object sender, EventArgs e)
        {
            QuitClient();
        }

        /// <summary>
        /// Used for hide on minimise
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClientResize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                HideForm();
            }
        }

        #region DEBUG Menu Functions
        /// <summary>
        /// Plays a windows sound file to test the lan chat core audio player
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DEBUGPlaySoundFunction(object sender, EventArgs e)
        {
            System.Media.SoundPlayer soundTest = new System.Media.SoundPlayer();

            //this should exist
            //if it doesnt someones windows installation is messed up!
            soundTest.SoundLocation = @"c:\Windows\Media\tada.wav";

            soundTest.Play();

            soundTest.Dispose();
        }

        /// <summary>
        /// Displays a sample private chat form for debugging
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DEBUGShowPrivateChatFunction(object sender, EventArgs e)
        {
            PrivateChat privateTest = new PrivateChat();
            privateTest.ShowDialog();
            privateTest.Dispose();
        }

        /// <summary>
        /// Adds a debug log entry stating the language and theme settings
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DEBUGTestLogFunction(object sender, EventArgs e)
        {
            String logText = String.Concat("LANCHAT TEST LOG ENTRY |", "Language: ", Properties.Settings.Default.Language, " | Theme: ", Properties.Settings.Default.Theme, " | END TEST ENTRY");
            LogHelper.DbgLog(logText);
        }
        #endregion

        private void trayIconDoubleClick(object sender, MouseEventArgs e)
        {
            UnHide();
        }
    }
}